﻿using System.Collections.Generic;
using GeneticAlgorithms.Genomes;

namespace System.Linq
{
    /// <summary>
    /// Provides additional extension methods for multiple
    /// collection interfaces.
    /// </summary>
    public static class ICollectionsExtender
    {
        /// <summary>
        /// Iterates through the enumerable, applying
        /// the provided action to each item in it.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">The enumerable genome to be iterated.</param>
        /// <param name="action">The action to perform on each single item.</param>
        public static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
        {
            foreach (T item in list)
            {
                action(item);
            }
        }

        /// <summary>
        /// Iterates through the enumerable, applying
        /// the provided action to each item in it.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">The enumerable genome to be iterated.</param>
        /// <param name="action">The action to perform on each single item. 
        /// Also receives the index as parameter.</param>
        public static void ForEach<T>(this IList<T> list, Action<T, int> action)
        {
            for (int i = 0; i < list.Count; ++i)
            {
                action(list[i], i);
            }
        }

        /// <summary>
        /// Iterates through the enumerable, applying
        /// the provided action to each item in it.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">The genome to be iterated.</param>
        /// <param name="valueGetter">
        /// The function that will be used to get the values. It will
        /// receive the index as its input parameter.
        /// </param>
        public static void SetValues<T>(this IList<T> list, Func<int, T> valueGetter)
        {
            for (int i = 0; i < list.Count; ++i)
            {
                list[i] = valueGetter(i);
            }
        }

        /// <summary>
        /// Iterates through the enumerable, applying
        /// the provided action to each item in it.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">The genome to be iterated.</param>
        /// <param name="value">The value to assign to all items in the genome.</param>
        public static void SetValues<T>(this IList<T> list, T value)
        {
            for (int i = 0; i < list.Count; ++i)
            {
                list[i] = value;
            }
        }


        /// <summary>
        /// Iterates through the enumerable, applying
        /// the provided action to each item in it.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="genome">The genome to be iterated.</param>
        /// <param name="valueGetter">
        /// The function that will be used to get the values. It will
        /// receive the index as its input parameter.
        /// </param>
        public static void SetValues<T>(this IGenome<T> genome, Func<int, T> valueGetter)
        {
            for (int i = 0; i < genome.Length; ++i)
            {
                genome[i] = valueGetter(i);
            }
        }


        /// <summary>
        /// Sets the values of the list.
        /// </summary>
        /// <typeparam name="T">Type of each item in the list</typeparam>
        /// <param name="genome">The genome.</param>
        /// <param name="value">The value.</param>
        public static void SetValues<T>(this IGenome<T> genome, T value)
        {
            for (int i = 0; i < genome.Length; ++i)
            {
                genome[i] = value;
            }
        }
    }
}
